home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Applications / µSim 1.1 / source / Simulator.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-25  |  10.9 KB  |  410 lines  |  [TEXT/CWIE]

  1. /*
  2. Copyright © 1993-1997 Fabrizio Oddone
  3. ••• ••• ••• ••• ••• ••• ••• ••• ••• •••
  4. This source code is distributed as freeware:
  5. you may copy, exchange, modify this code.
  6. You may include this code in any kind of application: freeware,
  7. shareware, or commercial, provided that full credits are given.
  8. You may not sell or distribute this code for profit.
  9. */
  10.  
  11.  
  12. #pragma fourbyteints on
  13. #include    <stdlib.h>
  14. #pragma fourbyteints reset
  15.  
  16. #include    "UtilsSys7.h"
  17. #include    "SimResIDs.h"
  18.  
  19. #include    "Globals.h"
  20. #include    "AEHandlers.h"
  21. #include    "Animation.h"
  22. #include    "Compares.h"
  23. #include    "Dump.h"
  24. #include    "Input.h"
  25. #include    "Microprogram_Ed.h"
  26. #include    "Registers.h"
  27. #include    "Simulator.h"
  28. #include    "SimUtils.h"
  29.  
  30. #if defined(FabSystem7orlater)
  31.  
  32. //#pragma segment Main
  33.  
  34. enum conditions {
  35. kCOND_NEVER = 0,
  36. kCOND_N,
  37. kCOND_Z,
  38. kCOND_ALWAYS
  39. };
  40.  
  41. static const short reading[] = { kP_MBR, kP_MBRMEM, 0};
  42. static const short readstart[] = { kP_MAR2MEM, 0};
  43. static const short writestart[] = { kP_MBRMEM, kP_MAR2MEM, 0};
  44.  
  45. static short    Abus, Bbus, Cbus;
  46. static union u_mir mir;
  47.  
  48. static short alu(void);
  49. static void shifter(void);
  50. static Boolean memory(void);
  51.  
  52. /* MSL: models the Micro Sequencing Logic */
  53. #define MSL()    ((mir.bits.cond == kCOND_ALWAYS) || ((mir.bits.cond == kCOND_Z) && \
  54.                 (gParts[kP_ALU - kFIRST_PICT] == 0)) || ((mir.bits.cond == kCOND_N) \
  55.                 && (gParts[kP_ALU - kFIRST_PICT] < 0)))
  56.  
  57. /* AMUX: models the A multiplexer */
  58. #define    AMUX()    (mir.bits.amux ? gParts[kP_MBR - kFIRST_PICT] : \
  59.                     gParts[kP_ALATCH - kFIRST_PICT])
  60.  
  61. /* MMUX: models the M multiplexer */
  62. #define    MMUX()    ((mslflag = MSL()) ? mir.bits.addr : gParts[kP_INCR - kFIRST_PICT])
  63.  
  64. /* alu: models the Arithmetic Logical Unit */
  65.  
  66. static short alu(void)
  67. {
  68. short value;
  69.  
  70. value = AMUX();
  71. gParts[kP_AMUX - kFIRST_PICT] = value;
  72. switch (mir.bits.alu) {
  73.     case 1:    value += Bbus;
  74.         break;
  75.     case 2:    value &= Bbus;
  76.         break;
  77.     case 3:    value = ~value;
  78.         break;
  79.     }
  80. gParts[kP_ALU - kFIRST_PICT] = value;
  81. if (gRstatus > kST_STEPASM) {
  82.     ChangedBox(kP_AMUX - kFIRST_PICT);
  83.     ChangedBox(kP_ALU - kFIRST_PICT);
  84.     }
  85. return value;
  86. }
  87.  
  88. /* shifter: models the (!) shifter */
  89.  
  90. static void shifter(void)
  91. {
  92. short value;
  93.  
  94. value = alu();
  95. switch (mir.bits.shift) {
  96.     case 1: value <<= 1;
  97.         break;
  98.     case 2: value = (unsigned short)value >> 1;
  99.         break;
  100.     case 3: value >>= 1;
  101.     }
  102. gParts[kP_SHIFTER - kFIRST_PICT] = value;
  103. if (gRstatus > kST_STEPASM) {
  104.     ChangedBox(kP_SHIFTER - kFIRST_PICT);
  105.     }
  106. Cbus = value;
  107. }
  108.  
  109. /* MAR: models the Memory Address Register */
  110.  
  111. #define MAR()    \
  112. {    \
  113. if (mir.bits.mar) {    \
  114.     gParts[kP_MAR - kFIRST_PICT] = gParts[kP_BLATCH - kFIRST_PICT];    \
  115.     if (gRstatus > kST_STEPASM) {    \
  116.         ChangedBox(kP_MAR - kFIRST_PICT);    \
  117.         if (gRstatus == kST_STEPSUBCYC)    \
  118.             ActivateObjs(marobjs);    \
  119.         }    \
  120.     }    \
  121. }
  122.  
  123. /* MBR: models the Memory Buffer Register */
  124.  
  125. #define MBR()    \
  126. {    \
  127. if (mir.bits.mbr) {    \
  128.     gParts[kP_MBR - kFIRST_PICT] = Cbus;    \
  129.     if (gRstatus > kST_STEPASM) {    \
  130.         ChangedBox(kP_MBR - kFIRST_PICT);    \
  131.         if (gRstatus == kST_STEPSUBCYC)    \
  132.             ActivateObjs(mbrobjs);    \
  133.         }    \
  134.     }    \
  135. }
  136.  
  137. /* ExecuteInstructions: executes instructions for a clock subcycle,
  138. taking care of the necessary user interface updates */
  139.  
  140. void ExecuteInstructions(short subclock)
  141. {
  142. static const short subc0[] = { kP_MPC2INC, kP_INCR, kP_MPC2CST, kP_CST2MIR, kP_REG2LTCH1, kP_REG2LTCH2, 0 };
  143. static const short subc1[] = { kP_ALATCH, kP_BLATCH, 0 };
  144. static const short shftaluamux[] = { kP_AMUX2ALU, kP_BLTCH2ALU, kP_ALU, kP_ALU2SH, kP_SHIFTER, 0};
  145. static const short shftoregs[] = { kP_SH2REGS1, kP_SH2REGS2, kP_SH2REGS3, 0 };
  146. static const short marobjs[] = { kP_MAR, kP_BLTCH2MAR1, kP_BLTCH2MAR2, 0 };
  147. static const short mbrobjs[] = { kP_MBR, kP_SH2MBR1, kP_SH2MBR2, 0 };
  148. static const short mapobjs[] = { kP_MAP, kP_MAPREGS, 0 };
  149. static const short fromabus[] = { kP_ALTCH2AMUX, kP_AMUX, 0 };
  150. static const short frommbr[] = { kP_MBR2AMUX, kP_AMUX, 0 };
  151. static const short fromincr[] = { kP_INC2MMUX1, kP_INC2MMUX2, kP_MMUX, kP_MPC, 0};
  152. static const short frommir[] = { kC_ADDR1, kC_ADDR2, kP_MMUX, kP_MPC, 0 };
  153. static const short mmux2mpc[] = { kP_MMUX2MPC, 0 };
  154.  
  155. Handle    tempH;
  156. Ptr    base;
  157. static unsigned short    mapLine;
  158. static Boolean    mslflag;
  159.  
  160. switch (subclock) {
  161.     case 0:
  162.         gParts[kP_INCR - kFIRST_PICT] = gParts[kP_MPC - kFIRST_PICT] + 1;
  163.         if (gRstatus > kST_STEPASM) {
  164.             ChangedBox(kP_INCR - kFIRST_PICT);
  165.             if (gRstatus == kST_STEPSUBCYC) {
  166.                 DeactivateObjs(shftoregs);
  167.                 DeactivateObjs(mbrobjs);
  168.                 DeactivateObjs(mapobjs);
  169.                 DeactivateObjs(writestart);
  170.                 if (mslflag)
  171.                     DeactivateObjs(frommir);
  172.                 else
  173.                     DeactivateObjs(fromincr);
  174.                 ActivateObjs(subc0);
  175.                 if (mir.bits.map)
  176.                     SelectLLine(kL_INSTR, mapLine);
  177.                 else {
  178.                     DeactivateObjs(mmux2mpc);
  179.                     SelectLLine(kL_COMMENTS, gParts[kP_MPC - kFIRST_PICT]);
  180.                     }
  181.                 }
  182.             }
  183.         mir = gCsMemory[gParts[kP_MPC - kFIRST_PICT]];
  184.         Abus = gRegs[mir.bits.a];
  185.         Bbus = gRegs[mir.bits.b];
  186.         break;
  187.     case 1:
  188.         gParts[kP_ALATCH - kFIRST_PICT] = Abus;
  189.         gParts[kP_BLATCH - kFIRST_PICT] = Bbus;
  190.         if (gRstatus > kST_STEPASM) {
  191.             ChangedBox(kP_ALATCH - kFIRST_PICT);
  192.             ChangedBox(kP_BLATCH - kFIRST_PICT);
  193.             if (gRstatus == kST_STEPSUBCYC) {
  194.                 DeactivateObjs(subc0);
  195.                 ActivateObjs(subc1);
  196.                 }
  197.             }
  198.         break;
  199.     case 2:
  200.         shifter();
  201.         MAR()
  202.         if (gRstatus == kST_STEPSUBCYC) {
  203.             DeactivateObjs(subc1);
  204.             ActivateObjs(shftaluamux);
  205.             if (mir.bits.amux)
  206.                 ActivateObjs(frommbr);
  207.             else
  208.                 ActivateObjs(fromabus);
  209.             }
  210.         break;
  211.     case 3:
  212.         if (mir.bits.dsc == 0) {
  213.             gRegs[mir.bits.c] = Cbus;
  214.             if (gRstatus > kST_STEPASM) {
  215.                 ChangedRegister(mir.bits.c);
  216.                 if (gRstatus == kST_STEPSUBCYC)
  217.                     ActivateObjs(shftoregs);
  218.                 }
  219.             }
  220.         MBR()
  221.         gParts[kP_MPC - kFIRST_PICT] = gParts[kP_MMUX - kFIRST_PICT] = MMUX();
  222.         (void)memory();
  223.         if (mir.bits.map) {
  224. //#define    Ext12(x)    (((x) << 4) >> 4)
  225. //#define    Ext11(x)    (((x) << 5) >> 5)
  226.             gRegs[kREG_EXT12] = gRegs[kREG_IR] << 4;
  227.             gRegs[kREG_EXT12] >>= 4;
  228.             gRegs[kREG_EXT11] = gRegs[kREG_IR] << 5;
  229.             gRegs[kREG_EXT11] >>= 5;
  230.             gRegs[kREG_LOW8] = gRegs[kREG_IR] & 0x00FF;
  231.             gParts[kP_MPC - kFIRST_PICT] = *(gAssMemory + *(Byte *)&gRegs[kREG_IR]);
  232.             if (gRstatus > kST_STEPASM) {
  233.                 ChangedRegister(kREG_EXT12);
  234.                 ChangedRegister(kREG_EXT11);
  235.                 ChangedRegister(kREG_LOW8);
  236.                 tempH = Get1Resource(krInstructions, kOPCODES);
  237.                 base = StripAddress(&((ROpcodePtr)*tempH)->offsetHB) + 2;
  238.                 mapLine = (unsigned)(StripAddress(bsearch(&gRegs[kREG_IR], base,
  239.                     *(unsigned short *)*tempH + 1, sizeof(ROpcode), compareOpc))
  240.                     - base) / (unsigned)sizeof(ROpcode);
  241.                 ZoomEffectMap2MPC();
  242.                 if (gRstatus == kST_STEPSUBCYC)
  243.                     ActivateObjs(mapobjs);
  244.                 else
  245.                     SelectLLine(kL_INSTR, mapLine);
  246.                 }
  247.             }
  248.         if (gRstatus > kST_STEPASM) {
  249.             ChangedBox(kP_MMUX - kFIRST_PICT);
  250.             ChangedBox(kP_MPC - kFIRST_PICT);
  251.             if (gRstatus == kST_STEPSUBCYC) {
  252.                 DeactivateObjs(shftaluamux);
  253.                 DeactivateObjs(marobjs);
  254.                 if (mir.bits.amux)
  255.                     DeactivateObjs(frommbr);
  256.                 else
  257.                     DeactivateObjs(fromabus);
  258.                 if (mslflag)
  259.                     ActivateObjs(frommir);
  260.                 else
  261.                     ActivateObjs(fromincr);
  262.                 if (mir.bits.map == 0)
  263.                     ActivateObjs(mmux2mpc);
  264.                 }
  265.             else
  266.                 SelectLLine(kL_COMMENTS, gParts[kP_MPC - kFIRST_PICT]);
  267.             }
  268.         break;
  269.     }
  270. }
  271.  
  272. /* memory: models the external RAM memory */
  273.  
  274. static Boolean memory(void)
  275. {
  276. short *tempP;
  277. unsigned short    firstWordinWind;
  278. static Boolean rdInitiated = false, wrInitiated = false;
  279. Boolean    stoppedForIO = false;
  280.  
  281. if (mir.bits.rd) {
  282.     if (rdInitiated) {
  283.         tempP = ((short *)gMMemory + (unsigned short)gParts[kP_MAR - kFIRST_PICT]);
  284.         gParts[kP_MBR - kFIRST_PICT] = *tempP;
  285.         if (gRstatus > kST_STEPASM) {
  286.             ChangedBox(kP_MBR - kFIRST_PICT);
  287.             if (gRstatus == kST_STEPSUBCYC)
  288.                 ActivateObjs(reading);
  289.             }
  290. // handle memory mapped input
  291.         if ((Ptr)tempP == (gMMemory + kSIZE_RAM - 4)) {
  292.             if (gInTheForeground == false || gWPtr_IO != FrontWindow()) {
  293.                 SendmyAE(kFCR_MINE, kAEmySignalIO, myIdleFunct, kAENoReply | kAEAlwaysInteract | kAECanSwitchLayer);
  294.                 stoppedForIO = true;
  295.                 }
  296.             }
  297.         rdInitiated = false;
  298.         }
  299.     else {
  300.         rdInitiated = true;
  301.         if (gRstatus == kST_STEPSUBCYC)
  302.             ActivateObjs(readstart);
  303.         }
  304.     }
  305. if (mir.bits.wr) {
  306.     if (wrInitiated) {
  307.         tempP = ((short *)gMMemory + (unsigned short)gParts[kP_MAR - kFIRST_PICT]);
  308.         *tempP = gParts[kP_MBR - kFIRST_PICT];
  309.         wrInitiated = false;
  310. // update Dump Window only if necessary
  311.         if (EmptyRgn(gWPtr_Dump->visRgn) == false)
  312.             if ((firstWordinWind = (unsigned short)GetDumpVScrollValue() << 4)
  313.                                 <= (unsigned short)gParts[kP_MAR - kFIRST_PICT])
  314.                 if (((firstWordinWind - 1) + 
  315.                         ((PRCT_B(gWPtr_Dump) - PRCT_T(gWPtr_Dump)) / GetDumpLineHeight()) << 3)
  316.                         >= (unsigned short)gParts[kP_MAR - kFIRST_PICT])
  317.                     InvalDump();
  318. // handle memory mapped output
  319.         if ((Ptr)tempP == (gMMemory + kSIZE_RAM - 2)) {
  320.             DoKeyDown(gWPtr_IO, ((unsigned char *)tempP)[1], false);
  321.             if (gInTheForeground == false || gWPtr_IO != FrontWindow())
  322.                 SendmyAE(kFCR_MINE, kAEmySignalIO, myIdleFunct, kAENoReply | kAEAlwaysInteract | kAECanSwitchLayer);
  323.             *tempP = 0;
  324.             }
  325.         }
  326.     else {
  327.         wrInitiated = true;
  328.         if (gRstatus == kST_STEPSUBCYC)
  329.             ActivateObjs(writestart);
  330.         }
  331.     }
  332. return stoppedForIO;
  333. }
  334.  
  335. /* ExecuteInstructionsGO: executes a conventional instruction of the
  336. simulated program, updating only the Dump window */
  337.  
  338. void ExecuteInstructionsGO(void)
  339. {
  340. enum {
  341. kMAX_COMPUTE = 120L
  342. };
  343.  
  344. unsigned long    tickc;
  345. unsigned long    interval;
  346. short value;
  347. Boolean    mslflag, hasPaused;
  348.  
  349. tickc = TickCount();
  350. do {
  351.     gParts[kP_INCR - kFIRST_PICT] = gParts[kP_MPC - kFIRST_PICT] + 1;
  352.     mir = gCsMemory[gParts[kP_MPC - kFIRST_PICT]];
  353.     gParts[kP_ALATCH - kFIRST_PICT] = gRegs[mir.bits.a];
  354.     gParts[kP_BLATCH - kFIRST_PICT] = gRegs[mir.bits.b];
  355.     value = AMUX();
  356.     gParts[kP_AMUX - kFIRST_PICT] = value;
  357.     switch(mir.bits.alu) {
  358.         case 1:    value += gParts[kP_BLATCH - kFIRST_PICT];
  359.             break;
  360.         case 2:    value &= gParts[kP_BLATCH - kFIRST_PICT];
  361.             break;
  362.         case 3:    value = ~value;
  363.             break;
  364.         }
  365.     gParts[kP_ALU - kFIRST_PICT] = value;
  366.     switch(mir.bits.shift) {
  367.         case 1: value <<= 1;
  368.             break;
  369.         case 2: value = (unsigned short)value >> 1;
  370.             break;
  371.         case 3: value >>= 1;
  372.         }
  373.     gParts[kP_SHIFTER - kFIRST_PICT] = value;
  374.     if (mir.bits.mar)
  375.         gParts[kP_MAR - kFIRST_PICT] = gParts[kP_BLATCH - kFIRST_PICT];
  376.     if (mir.bits.dsc == 0)
  377.         gRegs[mir.bits.c] = value;
  378.     if (mir.bits.mbr)
  379.         gParts[kP_MBR - kFIRST_PICT] = value;
  380.     gParts[kP_MPC - kFIRST_PICT] = gParts[kP_MMUX - kFIRST_PICT] = MMUX();
  381.     hasPaused = memory();
  382.     if (mir.bits.map) {
  383.         gRegs[kREG_EXT12] = gRegs[kREG_IR] << 4;
  384.         gRegs[kREG_EXT12] >>= 4;
  385.         gRegs[kREG_EXT11] = gRegs[kREG_IR] << 5;
  386.         gRegs[kREG_EXT11] >>= 5;
  387.         gRegs[kREG_LOW8] = gRegs[kREG_IR] & 0x00FF;
  388.         gParts[kP_MPC - kFIRST_PICT] = *(gAssMemory + *(Byte *)&gRegs[kREG_IR]);
  389.         }
  390.     interval = TickCount() - tickc;
  391.     }
  392. while (gParts[kP_MPC - kFIRST_PICT] && interval < kMAX_COMPUTE);
  393. if (gPrefs.infLoopsDetect && hasPaused == false && interval >= kMAX_COMPUTE && gParts[kP_MPC - kFIRST_PICT]) {
  394.     (void)StopAlert_AE(kALRT_INFLOOP, myStdFilterProcNoCancel, myIdleFunct);
  395.     StopIt();
  396.     }
  397. }
  398.  
  399. /* StopIt: stops the processing */
  400.  
  401. void StopIt(void)
  402. {
  403. gRstatus = kST_STOPPED;
  404. ChangedAllRegisters();
  405. ChangedAllBoxes();
  406. }
  407.  
  408. #endif
  409.  
  410.